#pragma once
#include<map>
#include"EventLoop.h"
#include"Socket.h"
#include"Channel.h"
#include"Acceptor.h"
#include"Connection.h"
#include"ThreadPool.h"

class Acceptor;

// TCP网络服务类
class TcpServer
{
private:
    // 主事件循环[服务端的连接分配给主事件循环，让主事件循环只处理新连接]
    EventLoop *mainLoop_;
    // 从事件循环[客户端的连接都分配给从事件循环，让从事件循环处理客户端的所有事件，如回复消息的逻辑，断开连接，消息发送完毕等]
    std::vector<EventLoop*> subLoops_;
    // 线程池
    ThreadPoll *threadPoll_;
    // 线程池大小，即从事件循环的个数【即主线程循环并不会使用到线程池里面】
    int threadNum_;
    // 一个TcpServer只有一个Acceptor对象
    Acceptor *acceptor_;
    // 一个TcpServer可以有多个Connection对象，存放在map中，key是该Connection的fd
    std::map<int, std::shared_ptr<Connection>> conns_;
    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 这部分回调函数可称之为接口，提供给外部调用实现的

    // 处理客户端的新连接，由业务层实现，目前是EchoServer::HandleNewConnection
    std::function<void(std::shared_ptr<Connection>)> newconnectioncallback_;
    // 处理客户端的连接端口，由业务层实现，目前是EchoServer::HandleCloseConnection
    std::function<void(std::shared_ptr<Connection>)> closeconnectioncallback_;
    // 处理客户端的连接错误，由业务层实现，目前是EchoServer::HandleErrorConnection
    std::function<void(std::shared_ptr<Connection>)> errorconnectioncallback_;
    // 处理客户端的消息处理，由业务层实现，目前是EchoServer::HandleMessage
    std::function<void(std::shared_ptr<Connection>, std::string&)> onmessagecallback_;
    // 处理发送缓冲区数据完成后的逻辑，由业务层实现，目前是EchoServer::HandleSendComplete
    std::function<void(std::shared_ptr<Connection>)> sendcompletecallback_;
    // 处理epoll_wait超时后的逻辑，由业务层实现，目前是EchoServer::HandlEpollTimeOut
    std::function<void(EventLoop*)> epolltimeoutcallback_;

    ////////////////////////////////////////////////////////////////////////////////////////////////
public:
    TcpServer(const std::string &ip, const uint16_t port, int threadNum = 3);
    ~TcpServer();
    // 运行事件循环
    void start();
    // 处理新客户端连接请求，在Acceptor类中回调此函数
    void newconnection(Socket *clientsock);
    // 关闭客户端的连接，在Connection类中回调此函数
    void closeconnection(std::shared_ptr<Connection> conn);
    // 客户端的连接错误，在Connection类中回调此函数
    void errorconnection(std::shared_ptr<Connection> conn);
    // 处理客户端的请求报文，在Connection类中回调此函数
    void message(std::shared_ptr<Connection> conn, std::string& message);
    // 缓冲区数据发送完成后，在Connection中回调此函数
    void sendcomplete(std::shared_ptr<Connection> conn);
    // epoll_wait超时，在EventLoop中回调此函数
    void epolltimeout(EventLoop *loop);
    // 设置newconnectioncallback_回调函数
    void setnewconnectioncallback(std::function<void(std::shared_ptr<Connection>)> fn);
    // 设置closeconnectioncallback_回调函数
    void setcloseconnectioncallback(std::function<void(std::shared_ptr<Connection>)> fn);
    // 设置errorconnectioncallback_回调函数
    void seterrorconnectioncallback(std::function<void(std::shared_ptr<Connection>)> fn);
    // 设置onmessagecallback_回调函数
    void setonmessagecallback(std::function<void(std::shared_ptr<Connection>, std::string&)> fn);
    // 设置sendcompletecallback_回调函数
    void setsendcompletecallback(std::function<void(std::shared_ptr<Connection>)> fn);
    // 设置epolltimeoutcallback_回调函数
    void setepolltimeoutcallback(std::function<void(EventLoop*)> fn);
};